#include "BuildManager.h"
#include "DialogReflection.h"
#include "EItemManager.h"
#include "qnamespace.h"
#include "qwidget.h"
#include <QPushButton>
#include <WidgetsManager.h>
#include <WidgetMainWindow.h>
#include <WidgetTree.h>
#include <WidgetLog.h>
#include <DialogTypeList.h>
#include <DialogDataMonitor.h>
#include <DialogReflection.h>
#include <DialogPlugin.h>
#include <WidgetVariantContainer.h>
#include <WidgetProperty.h>
#include <UIFunction.h>
#include <EPluginLoader.h>
#include <ECommandManager.h>
#include <cstdint>

// #include <RegFunctionOsg.h>
// #include <RegFunctionOsg_gen.h>
// #include <RegFunctionMachining.h>
// #include <RegFunctionVtk.h>

BuildManager* BuildManager::_instance = NULL;
BuildManager::BuildManager()
{

}
BuildManager::~BuildManager()
{

}

BuildManager* BuildManager::instance()
{
    if (_instance == NULL)
    {
        _instance = new BuildManager();
    }
    return _instance;

}

void BuildManager::buildUi()
{
	this->buildMainWindow();


    WidgetTree* tree = dynamic_cast<WidgetTree*>(WidgetsManager::instance()->getWidgetFromMap("WidgetTree"));

    QWidget* varContainer = WidgetsManager::instance()->getWidgetFromMap("WidgetVariantContainer");

    QWidget* mainWin = WidgetsManager::instance()->getWidgetFromMap("WidgetMainWindow");

    //
    QObject::connect(tree, 
                     SIGNAL(signalSelectItemBase(ItemBasePtr )),
                     varContainer,
                     SLOT(slotSelectItemBase(ItemBasePtr ))
                     );

    QObject::connect(tree, 
                     SIGNAL(signalDisSelectItemBase(ItemBasePtr )),
                     varContainer,
                     SLOT(slotDisSelectItemBase(ItemBasePtr ))
                     );

    this->loadPlugins();

    //Init dialog 
    QWidget* wDataMonitor = buildDialogDataMonitor();
    QWidget* wReflection = buildDialogDataMonitor();

    buildDialogPlugin();
    buildDialogTypeList();
}

QWidget* BuildManager::buildMainWindow()
{
	WidgetMainWindow* widgetPtr = new WidgetMainWindow();

	// WidgetsManager::instance()->setCentralWidget(widgetPtr);
	WidgetsManager::instance()->addWidgetToMap("WidgetMainWindow", widgetPtr);

    WidgetTree* wTree = (WidgetTree*)buildWidgetTree();
    widgetPtr->setWidgetToDockLeft(wTree);
    
    // WidgetVariantContainer* wContainer = (WidgetVariantContainer*)buildWidgetVariantContainer();
    // widgetPtr->setWidgetToDockRight(wContainer);
    // wContainer->getController()->addCmdSenderList(wTree->getController()->getTag());

    WidgetProperty* wProperty = (WidgetProperty*)buildWidgetProperty();
    widgetPtr->setWidgetToDockRight(wProperty);
    wProperty->getController()->addCmdSenderList(wTree->getController()->getTag());
    // wProperty->getController()->addCmdSenderList(wProperty->getController()->getTag());
	

    QWidget* wLog = buildWidgetLog();
    widgetPtr->setWidgetToDockDown(wLog);

	return widgetPtr;
}

QWidget* BuildManager::buildWidgetTree()
{
	WidgetTree* widgetPtr = new WidgetTree();
    WidgetsManager::instance()->addWidgetToMap("WidgetTree", widgetPtr);

    widgetPtr->getController()->setRootItem(EItemManager::instance()->getItemTreeRoot());
    widgetPtr->getController()->refresh();

    ECommandManager::instance()->registDelegate(
            MakeDelegate(&EController::handleCommand, *widgetPtr->getController())
            );

	return widgetPtr;
}

QWidget* BuildManager::buildDialogTypeList()
{
	DialogTypeList* widgetPtr = new DialogTypeList();
    WidgetsManager::instance()->addWidgetToMap("DialogTypeList", widgetPtr);

    widgetPtr->getController()->setRootItem(EItemManager::instance()->getItemTypeRoot());
    widgetPtr->getController()->refresh();
    widgetPtr->getTreeWidget()->expandAll();
    

    // widgetPtr->addToList("EItem");
	return widgetPtr;
}

QWidget* BuildManager::buildDialogDataMonitor()
{
	DialogDataMonitor* widgetPtr = new DialogDataMonitor();
    WidgetsManager::instance()->addWidgetToMap("DialogDataMonitor", widgetPtr);
    return widgetPtr;
}

QWidget* BuildManager::buildDialogReflection()
{
	DialogReflection* widgetPtr = new DialogReflection();
    WidgetsManager::instance()->addWidgetToMap("DialogReflection", widgetPtr);
    return widgetPtr;
}

QWidget* BuildManager::buildDialogPlugin()
{
	DialogPlugin* widgetPtr = new DialogPlugin();
    WidgetsManager::instance()->addWidgetToMap("DialogPlugin", widgetPtr);
    widgetPtr->updateFromPluginLoader();
    return widgetPtr;
}

QWidget* BuildManager::buildWidgetVariantContainer()
{
	WidgetVariantContainer* widgetPtr = new WidgetVariantContainer();
	WidgetsManager::instance()->addWidgetToMap("WidgetVariantContainer", widgetPtr);

    ECommandManager::instance()->registDelegate(
            MakeDelegate(&EController::handleCommand, *widgetPtr->getController())
            );


	return widgetPtr;
}

QWidget* BuildManager::buildWidgetProperty()
{
	WidgetProperty* widgetPtr = new WidgetProperty();
	WidgetsManager::instance()->addWidgetToMap("WidgetProperty", widgetPtr);
    ECommandManager::instance()->registDelegate(
            MakeDelegate(&EController::handleCommand, *widgetPtr->getController())
            );
	return widgetPtr;
}

QWidget* BuildManager::buildWidgetEmpty()
{
	QPushButton* widgetPtr = new QPushButton();

	return widgetPtr;
}

QWidget* BuildManager::buildWidgetLog()
{
    WidgetLog* widgetPtr = new WidgetLog();
    WidgetsManager::instance()->addWidgetToMap("WidgetLog", widgetPtr);

    log_add_callback(UIFun::callback_ui_log, nullptr, 0);

    return widgetPtr;
}

#include <EPluginOsg.h>
void BuildManager::loadPlugins()
{
    EPluginLoader::instance()->loadPlugin("PluginDefaultd");
    EPluginPtr pp = new EPluginOsg;
    pp->registThis();

    EPluginLoader::instance()->loadPlugin("PluginXmld");
    // loadLibUiWrapOsg();
    // loadLibUiWrapMachining();
    // loadLibUiWrapVtk();
}

void BuildManager::loadLibUiWrapOsg()
{
    // RegFunctionOsg::init();

}

void BuildManager::loadLibUiWrapMachining()
{
    // RegFunctionMachining::init();
}

void BuildManager::loadLibUiWrapVtk()
{
    // RegFunctionVtk::init();
}
